package com.doublefish.doublefishrobot.utils.socket;

import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.util.Log;

import androidx.annotation.NonNull;

import com.doublefish.doublefishrobot.base.DFService;
import com.doublefish.doublefishrobot.utils.AppCacheUtil;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;

/**
 * 作者:dugaofeng on 2025/1/15 10:56
 */
public class SocketClient {
    private static final String HOST = "192.168.5.1";
    private static final int PORT = 8081;

//    private static final String HOST = "172.16.8.89";
//    private static final int PORT = 8081;

    private Context mContext;
    Handler socketHandler = null;  //socket 连接 断开 发送数据
    Handler onReceiveDataHandler = null;  //socket读取数据
    Handler uihandler = null;   //跳转到主线程

    private boolean didConnected = false; // 是否已经连接

    private Socket socket = null;
    private BufferedWriter bw = null;
    private BufferedReader br = null;

    private SocketManager.OnSocketConnectListner onConnectListner;
    private SocketManager.OnSocketDisConnectListner onDisConnectListner;

    private SocketManager.OnSocketBallCountListner onSocketBallCountListner;

    private boolean isBackground = false;

    public SocketClient() {
        HandlerThread thread = new HandlerThread("socketThread");
        thread.start();
        socketHandler = new Handler(thread.getLooper());

        HandlerThread thread2 = new HandlerThread("onReceiveDataHandler");
        thread2.start();
        onReceiveDataHandler = new Handler(thread2.getLooper());

        uihandler = new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(@NonNull Message msg) {
                switch (msg.what) {
                    //10.连接成功 11.连接失败 20.receiveData
                    case 10:
                        didConnected = true;
                        if (onConnectListner != null) {
                            onConnectListner.onConnect(true);
                        }
                        break;
                    case 11:
                        didConnected = false;
                        if (onConnectListner != null) {
                            onConnectListner.onConnect(false);
                        }
                        break;
                    case 20:
                        if (onSocketBallCountListner != null) {
                            onSocketBallCountListner.onBallCount(msg.arg1);
                        }
                        break;
                    case 30:
                        didConnected = false;
                        if (onConnectListner != null) {
                            onConnectListner.onConnect(false);
                        }
                        if (onDisConnectListner != null) {
                            onDisConnectListner.onDisConnect();
                        }
                        //停止播放音频
                        stopSilentMp3IfNeeded();
                        break;
                    default:
                        break;
                }
            }
        };
    }

    public void setContext(Context mContext) {
        this.mContext = mContext;
    }

    public void setBackground(boolean background) {
        isBackground = background;
    }

    //是否已连接
    public boolean didConnected() {
        return socket != null && didConnected;
    }

    public void connectToSocket(SocketManager.OnSocketConnectListner onConnectListner) {
        this.onConnectListner = onConnectListner;

        socketHandler.post(new Runnable() {
            @Override
            public void run() {
                connect();
            }
        });

    }

    //开始监听回调数据
    public void startReceiveData() {
        onReceiveDataHandler.post(new Runnable() {
            @Override
            public void run() {
                onReceivData();
            }
        });
    }

    //断卡socket
    public void setOnDisConnectListner(SocketManager.OnSocketDisConnectListner onDisConnectListner) {
        this.onDisConnectListner = onDisConnectListner;
    }

    public void disConnectSocket() {
        socketHandler.post(new Runnable() {
            @Override
            public void run() {
                disConnect();
            }
        });
    }

    public void setOnSocketBallCountListner(SocketManager.OnSocketBallCountListner onSocketBallCountListner) {
        this.onSocketBallCountListner = onSocketBallCountListner;
    }

//    public void onSocketNoti() {
//        socketHandler.post(new Runnable() {
//            @Override
//            public void run() {
//                onNoti();
//            }
//        });
//    }
//
//    public void offSocketNoti() {
//        socketHandler.post(new Runnable() {
//            @Override
//            public void run() {
//                offNoti();
//            }
//        });
//    }

    //发送数据
    public void sendSocketData(char[] data) {
        socketHandler.post(new Runnable() {
            @Override
            public void run() {
                sendData(data);
            }
        });
    }

    public void listnerConnectState() {
        if (uihandler == null) {
            return;
        }
        if (socket == null) {
            uihandler.sendEmptyMessage(30);
            return;
        }
       if (!didConnected()) {
           uihandler.sendEmptyMessage(30);
       }
    }

    //连接socket
    private void connect() {
        try {
            SocketAddress socketAddress = new InetSocketAddress(HOST, PORT);
            int timeout = 10000; // 连接超时时间，单位毫秒
            socket = new Socket();
            socket.connect(socketAddress, timeout);
            if (uihandler != null) {
                uihandler.sendEmptyMessage(10);
            }
        } catch (IOException e) {
            e.printStackTrace();
            if (uihandler != null) {
                uihandler.sendEmptyMessage(11);
            }
        }
    }

    //断卡socket
    private void disConnect() {
        if (bw != null) {
            try {
                bw.close();
                bw = null;
            } catch (Exception e) {
                e.printStackTrace();
                bw = null;
            }
        }
        if (socket != null ) {
            try {
                socket.close();
                socket = null;
            } catch (Exception e) {
                e.printStackTrace();
                socket = null;
            }
        }
        //必须将br.close()写到socket.close()的后面，否则br.close会卡柱线程
        if (br != null) {
            try {
                br.close();
                br = null;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    //发送数据
    private void sendData(char[] data) {
        if (data == null) {
            return;
        }
        if (socket == null || socket.isClosed()) {
            return;
        }
        try {
            if (bw == null) {
                OutputStream os = socket.getOutputStream();
                bw = new BufferedWriter(new OutputStreamWriter(os));
            }
            bw.write(data);
            bw.flush();
        } catch (Exception e) {
            e.printStackTrace();
            disConnect();
        }
    }

    //组包的数据
    private static int MAX_SIZE = 1024;
    private char[] dataBuffer = new char[MAX_SIZE];  //做一个循环的数组
    private int startIndex = 0; //byteBuffer 循环数组的当前起始下标
    private int endIndex = 0; //byteBuffer 循环数组的当前结束下标

    //监听回调数据
    private void onReceivData() {
        try {
            if (socket == null) {
                if (uihandler != null) {
                    Message message = new Message();
                    message.what = 20;
                    message.arg1 = 0;
                    uihandler.sendMessage(message);
                }
                return;
            }
            if (br != null) {
                return;
            }
            InputStream in = socket.getInputStream();
            br = new BufferedReader(new InputStreamReader(in));

            char[] read = new char[128];
            int length = 0;
            while ((length = br.read(read)) > 0) {
                Log.i("length", "length = " + length);
                if (length > MAX_SIZE) {
                    continue;
                }
                //APP在后台运行时，反正看不到界面，可以不解析数据，以节省cpu
                if (isBackground) {
                    continue;
                }
                //先组包
                for (int i = 0; i < length; i++) {
                    dataBuffer[endIndex % MAX_SIZE] = read[i];
                    endIndex++;
                    endIndex %= MAX_SIZE;
                }
                //找包头
                findConmand();
            }

            //length == -1 说明发球机那边的socket断了
            Log.i("length-1", "length2 = " + length);
            disConnect();
        } catch (Exception e) {
            e.printStackTrace();
            disConnect();
        }
    }

    private void findConmand() {
        while (true) {
            if (startIndex == endIndex) {
                return;
            }
            //先找帧头
            if (dataBuffer[startIndex] == 'D'
                    || dataBuffer[(startIndex + 1) % MAX_SIZE] == 'F'
                    || dataBuffer[(startIndex + 2) % MAX_SIZE] == 'S'
                    || dataBuffer[(startIndex + 3) % MAX_SIZE] == '5') {

                char num4 = dataBuffer[(startIndex + 4) % MAX_SIZE];
                char num5 = dataBuffer[(startIndex + 5) % MAX_SIZE];
                char num6 = dataBuffer[(startIndex + 6) % MAX_SIZE];
                char num7 = dataBuffer[(startIndex + 7) % MAX_SIZE];
                if ((num4 >= '0' && num4 <= '9')
                        && (num5 >= '0' && num5 <= '9')
                        && (num6 >= '0' && num6 <= '9')
                        && (num7 >= '0' && num7 <= '9')) {
                    String number = String.format("%c%c%c%c", num4, num5, num6, num7);
                    try {
                        int count = Integer.parseInt(number);
                        if (uihandler != null) {
                            Message message = new Message();
                            message.what = 20;
                            message.arg1 = count;
                            uihandler.sendMessage(message);

                            startIndex += 8; //跳过'DFS5' + number
                            startIndex %= MAX_SIZE;
                        }
                    } catch (NumberFormatException e) {
                        e.printStackTrace();
                    }
                } else {
                    if (((startIndex + 4) % MAX_SIZE) >= endIndex) {
                        return;
                    } else {
                        startIndex += 4; //跳过'DFS5'
                        startIndex %= MAX_SIZE;
                    }
                }
            } else {
                startIndex++;
                startIndex %= MAX_SIZE;
            }
        }
    }

    //region  service ： 用于后台播放无声mp3

    //后台播放音频
    public void playSilentMp3IfNeeded() {
        // 超5的后台运行方案 默认0
        int bgPrograme = AppCacheUtil.getInstance().getBgProgram();
        if (bgPrograme != 0) {
            return;
        }
        // 超5的后台运行方案 播放MP3
        boolean bgPlayer = AppCacheUtil.getInstance().isBgPlayer();
        //后台播放MP3 且是 连接中，需要保活
        if (bgPlayer && SocketManager.getInstance().didConnected()) {
            //开启service
            startService();
        }
    }
    //停止音频
    public void stopSilentMp3IfNeeded() {
        // 超5的后台运行方案 默认0
        int bgPrograme = AppCacheUtil.getInstance().getBgProgram();
        if (bgPrograme != 0) {
            return;
        }

        // 超5的后台运行方案 播放MP3
        boolean bgPlayer = AppCacheUtil.getInstance().isBgPlayer();
        if (bgPlayer) {
            // 停止service
            stopService();
        }
    }

    private Intent serviceIntent = null;
    private void startService() {
        try {
//            Intent intent = new Intent(this, DFService.class);
//            startService(intent);
            serviceIntent = new Intent(mContext, DFService.class);
            mContext.startService(serviceIntent);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //停止service
    private void stopService() {
        try {
//            Intent intent = new Intent(this, DFService.class);
//            stopService(intent);
            if (serviceIntent != null) {
                mContext.stopService(serviceIntent);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            serviceIntent = null;
        }
    }

    //endregion
}
